package net.xdclass.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.component.StoreEngine;
import net.xdclass.config.AccountConfig;
import net.xdclass.config.MinioConfig;
import net.xdclass.controller.req.AccountLoginReq;
import net.xdclass.controller.req.AccountRegisterReq;
import net.xdclass.controller.req.FolderCreateReq;
import net.xdclass.dto.AccountDTO;
import net.xdclass.dto.StorageDTO;
import net.xdclass.enums.AccountRoleEnum;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.mapper.AccountFileMapper;
import net.xdclass.mapper.AccountMapper;
import net.xdclass.mapper.StorageMapper;
import net.xdclass.model.AccountDO;
import net.xdclass.model.AccountFileDO;
import net.xdclass.model.StorageDO;
import net.xdclass.service.AccountService;
import net.xdclass.util.CommonUtil;
import net.xdclass.util.SpringBeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * @author 姜阿木
 * @date 2025/5/15 17:29
 */
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountMapper  accountMapper;

    @Autowired
    private StoreEngine  fileStoreEngine;

    @Autowired
    private MinioConfig  minioConfig;

    @Autowired
    private AccountFileServiceImpl fileService;

    @Autowired
    private StorageMapper storageMapper;
    @Autowired
    private AccountFileMapper accountFileMapper;


    /**
     * 1、查询手机号
     * 2、密码加密
     * 3、插入数据库
     * 4、其他操作
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(AccountRegisterReq req) {

        // 1、查询手机号
        List<AccountDO> phone = accountMapper.selectList(new QueryWrapper<AccountDO>().eq("phone", req.getPhone()));
        if(!phone.isEmpty()){
            throw new BizException(BizCodeEnum.ACCOUNT_REPEAT);
        }

        AccountDO accountDO = SpringBeanUtil.copyProperties(req, AccountDO.class);

        //  2、密码加密
        String digestAsHex = DigestUtils.md5DigestAsHex((AccountConfig.ACCOUNT_SALT + req.getPassword()).getBytes());
        accountDO.setPassword(digestAsHex);
        accountDO.setRole(AccountRoleEnum.COMMON.name());

        // 3、插入数据库
        accountMapper.insert(accountDO);

        // 4、设置默认存储空间大小
        StorageDO storageDO = new StorageDO();
        storageDO.setAccountId(accountDO.getId());
        storageDO.setUsedSize(0L);
        storageDO.setTotalSize(AccountConfig.STORAGE_CONTROL_DEFAULT_SIZE);
        storageMapper.insert(storageDO);

        // 5、设置网盘根目录 初始化文件夹
        FolderCreateReq createFolderInit = FolderCreateReq.builder()
                .accountId(accountDO.getId())
                .folderName(AccountConfig.ROOT_FOLDER_NAME)
                .parentId(AccountConfig.ROOT_FOLDER_ID)
                .build();
        fileService.createFolder(createFolderInit);
    }

    @Override
    public String uploadAvatar(MultipartFile file) {
        String filename = CommonUtil.getFilePath(file.getOriginalFilename());
        fileStoreEngine.upload(minioConfig.getAvatarBucketName(), filename, file);
        return minioConfig.getEndpoint() + "/" + minioConfig.getAvatarBucketName() + "/" + filename;
    }

    @Override
    public AccountDTO login(AccountLoginReq req) {
        // 处理密码
        String digestAsHex = DigestUtils.md5DigestAsHex((AccountConfig.ACCOUNT_SALT + req.getPassword()).getBytes());
        AccountDO accountDO = accountMapper.selectOne(new QueryWrapper<AccountDO>().eq("phone", req.getPhone())
                .eq("password", digestAsHex));
        if(accountDO == null){
            throw  new BizException(BizCodeEnum.ACCOUNT_PWD_ERROR);
        }
        return SpringBeanUtil.copyProperties(accountDO, AccountDTO.class);
    }

    @Override
    public AccountDTO getDetail(Long accountId) {
        // 查询账号信息
        AccountDO accountDO = accountMapper.selectById(accountId);
        AccountDTO accountDTO = SpringBeanUtil.copyProperties(accountDO, AccountDTO.class);

        // 获取存储信息
        StorageDO storageDO = storageMapper.selectOne(new QueryWrapper<StorageDO>().eq("account_id", accountId));
        accountDTO.setStorageDTO(SpringBeanUtil.copyProperties(storageDO, StorageDTO.class));

        // 获取根文件信息
        AccountFileDO accountFileDO = accountFileMapper.selectOne(new QueryWrapper<AccountFileDO>()
                .eq("account_id", accountId)
                .eq("parent_id", AccountConfig.ROOT_FOLDER_ID)
        );

        accountDTO.setRootFolderId(accountFileDO.getId());
        accountDTO.setRootFolderName(accountFileDO.getFileName());

        return accountDTO;
    }
}
